package com.bestcem.xm.deliver.grpc.service;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bestcem.xm.deliver.convert.grpc.DeliverGrpcConvertMapper;
import com.bestcem.xm.deliver.entity.*;
import com.bestcem.xm.deliver.grpc.v1.services.*;
import com.bestcem.xm.deliver.mapper.*;
import io.grpc.stub.StreamObserver;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.server.service.GrpcService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import zhongyan.xm.base.v1.Base;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@GrpcService
@Slf4j
@RequiredArgsConstructor
public class BaseDeliverGrpcService extends com.bestcem.xm.deliver.grpc.v1.services.BaseDeliverServiceGrpc.BaseDeliverServiceImplBase {

    private static final Base.Status SUCCESS_STATUS = Base.Status.newBuilder().setCode(Base.Code.OK).build();
    private static final Base.Status FAIL_STATUS = Base.Status.newBuilder().setCode(Base.Code.ERROR).build();

    private @NonNull DeliverDeliverMapper deliverDeliverMapper;
    private @NonNull DeliverAgainDeliverTaskMapper deliverAgainDeliverTaskMapper;
    private @NonNull DeliverAgainDeliverRecordMapper deliverAgainDeliverRecordMapper;
    private @NonNull DeliverSurveyExtParamsVersionMapper deliverSurveyExtParamsVersionMapper;
    private @NonNull DeliverDeliverExtParamsMapper deliverDeliverExtParamsMapper;
    private @NonNull DeliverCustomLinkDeliverMapper deliverCustomLinkDeliverMapper;
    private @NonNull DeliverWechatmpRecordMapper deliverWechatmpRecordMapper;
    private @NonNull DeliverExtDeliverMappingMapper deliverExtDeliverMappingMapper;
    private @NonNull DeliverDeliverSurveyDataMapper deliverSurveyDataMapper;
    private @NonNull DeliverSurveyDeliverMapper deliverSurveyDeliverMapper;

    private @NonNull DeliverGrpcConvertMapper deliverGrpcConvertMapper;

    // 通过查询条件批量一次性获取所有符合条件的SurveyDeliver
    //rpc ListSurveyDeliver(ListSurveyDeliverRequest) returns (SurveyDeliverSearchResponse);
    @Override
    public void listSurveyDeliver(ListSurveyDeliverRequest request, StreamObserver<SurveyDeliverSearchResponse> responseObserver) {
        SurveyDeliverSearchResponse.Builder result = SurveyDeliverSearchResponse.newBuilder();

        LambdaQueryWrapper<DeliverSurveyDeliver> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StrUtil.isNotBlank(request.getSurveyDeliver().getDeliverId()), DeliverSurveyDeliver::getDeliverId, request.getSurveyDeliver().getDeliverId())
                .eq(StrUtil.isNotBlank(request.getSurveyDeliver().getSurveyId()), DeliverSurveyDeliver::getSurveyId, request.getSurveyDeliver().getSurveyId());
        List<DeliverSurveyDeliver> deliverSurveyDelivers = deliverSurveyDeliverMapper.selectList(wrapper);

        result.addAllSurveyDeliverList(deliverGrpcConvertMapper.toGrpcDeliverSurveyDeliverList(deliverSurveyDelivers));
        result.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getAgainDeliverRecord(GetAgainDeliverRecordRequest request, StreamObserver<AgainDeliverRecordResponse> responseObserver) {
        AgainDeliverRecordResponse.Builder result = AgainDeliverRecordResponse.newBuilder();
        DeliverAgainDeliverRecord deliverRecord = deliverAgainDeliverRecordMapper.selectById(request.getId());
        if (deliverRecord == null) {
            result.setStatus(Base.Status.newBuilder().setCode(Base.Code.ERROR).setMessage("AgainDeliverRecord not found").build());
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }
        AgainDeliverRecord againDeliverRecord = deliverGrpcConvertMapper.toGrpcAgainDeliverRecord(deliverRecord);
        result.setAgainDeliverRecord(againDeliverRecord);
        result.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listAgainDeliverTask(ListAgainDeliverTaskRequest request, StreamObserver<AgainDeliverTaskSearchResponse> responseObserver) {
        AgainDeliverTaskSearchResponse.Builder result = AgainDeliverTaskSearchResponse.newBuilder();
        AgainDeliverTask againDeliverTask = request.getAgainDeliverTask();
        String search = request.getSearch();
        List<Integer> status = request.getStatusList();
        List<String> fields = request.getFieldsList();

        // 可以参考LambdaQueryWrapper<DeliverDeliverExtParams> wrapper = new QueryWrapper<>(deliverGrpcConvertMapper.toDeliverDeliverExtParams(grpcParams)).lambda();
        LambdaQueryWrapper<DeliverAgainDeliverTask> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(againDeliverTask.getName())) {
            wrapper.eq(DeliverAgainDeliverTask::getName, againDeliverTask.getName());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getRawProjectId())) {
            wrapper.eq(DeliverAgainDeliverTask::getRawProjectId, againDeliverTask.getRawProjectId());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getDeliverProjectId())) {
            wrapper.eq(DeliverAgainDeliverTask::getDeliverProjectId, againDeliverTask.getDeliverProjectId());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getCreator())) {
            wrapper.eq(DeliverAgainDeliverTask::getCreator, againDeliverTask.getCreator());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getConditions())) {
            wrapper.eq(DeliverAgainDeliverTask::getConditions, againDeliverTask.getConditions());
        }
        wrapper.eq(DeliverAgainDeliverTask::getTtype, againDeliverTask.getTtypeValue());
        wrapper.eq(DeliverAgainDeliverTask::getChecksubmit, againDeliverTask.getChecksubmit() ? 1 : 0);
        wrapper.eq(DeliverAgainDeliverTask::getConditionRelation, againDeliverTask.getConditionRelationValue());
        if (StringUtils.isNotEmpty(againDeliverTask.getOrgId())) {
            wrapper.eq(DeliverAgainDeliverTask::getOrgId, againDeliverTask.getOrgId());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getSmsTemplateId())) {
            wrapper.eq(DeliverAgainDeliverTask::getSmsTemplateId, againDeliverTask.getSmsTemplateId());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getSmsTemplateContent())) {
            wrapper.eq(DeliverAgainDeliverTask::getSmsTemplateContent, againDeliverTask.getSmsTemplateContent());
        }
        if (StringUtils.isNotEmpty(againDeliverTask.getSmsTemplateTitle())) {
            wrapper.eq(DeliverAgainDeliverTask::getSmsTemplateTitle, againDeliverTask.getSmsTemplateTitle());
        }
        // 这里不会有0的判断问题，传过来一定是个列表
        // status, fields, fields 在表中都没有，没用到
        List<DeliverAgainDeliverTask> deliverAgainDeliverTasks = deliverAgainDeliverTaskMapper.selectList(wrapper);
        if (deliverAgainDeliverTasks != null) {
            deliverAgainDeliverTasks.forEach(deliverAgainDeliverTask -> {
                AgainDeliverTask deliverTask = deliverGrpcConvertMapper.toGrpcAgainDeliverTask(deliverAgainDeliverTask);
                result.addAgainDeliverTaskList(deliverTask);
            });
        }
        result.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getVersionBySurveyId(GetVersionBySurveyIdRequest request, StreamObserver<GetVersionBySurveyIdResponse> responseObserver) {
        GetVersionBySurveyIdResponse.Builder result = GetVersionBySurveyIdResponse.newBuilder();
        LambdaQueryWrapper<DeliverSurveyExtParamsVersion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeliverSurveyExtParamsVersion::getSurveyId, request.getSurveyId());
        DeliverSurveyExtParamsVersion survey_ext_params_version = deliverSurveyExtParamsVersionMapper.selectOne(wrapper);

        if (ObjectUtils.isEmpty(survey_ext_params_version)) {
            result.setStatus(FAIL_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        result.setStatus(SUCCESS_STATUS);
        result.setVersion(survey_ext_params_version.getVersion());
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    // 通过查询条件批量一次性获取所有符合条件的SurveyExtParamsVersion
    //rpc ListSurveyExtParamsVersion(ListSurveyExtParamsVersionRequest) returns (SurveyExtParamsVersionSearchResponse);
    @Override
    public void listSurveyExtParamsVersion(ListSurveyExtParamsVersionRequest request, StreamObserver<SurveyExtParamsVersionSearchResponse> responseObserver) {
        SurveyExtParamsVersionSearchResponse.Builder result = SurveyExtParamsVersionSearchResponse.newBuilder();
        LambdaQueryWrapper<DeliverSurveyExtParamsVersion> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DeliverSurveyExtParamsVersion::getSurveyId, request.getSurveyExtParamsVersion().getSurveyId());
        List<DeliverSurveyExtParamsVersion> list = deliverSurveyExtParamsVersionMapper.selectList(wrapper);
        result.setStatus(SUCCESS_STATUS);
        result.addAllSurveyExtParamsVersionList(deliverGrpcConvertMapper.toGrpcDeliverSurveyExtParamsVersionList(list));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listExtDeliverMapping(ListExtDeliverMappingRequest request, StreamObserver<ExtDeliverMappingSearchResponse> responseObserver) {
        ExtDeliverMappingSearchResponse.Builder result = ExtDeliverMappingSearchResponse.newBuilder();
        ExtDeliverMapping grpcParams = request.getExtDeliverMapping();
        String search = request.getSearch();
        DeliverExtDeliverMapping deliverExtDeliverMapping = deliverGrpcConvertMapper.toDeliverExtDeliverMapping(grpcParams);
        LambdaQueryWrapper<DeliverExtDeliverMapping> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(deliverExtDeliverMapping.getOrgId())) {
            queryWrapper.eq(DeliverExtDeliverMapping::getOrgId, deliverExtDeliverMapping.getOrgId());
        }
        if (ObjectUtil.isNotEmpty(deliverExtDeliverMapping.getSystemNo())) {
            queryWrapper.eq(DeliverExtDeliverMapping::getSystemNo, deliverExtDeliverMapping.getSystemNo());
        }
        if (ObjectUtil.isNotEmpty(deliverExtDeliverMapping.getConditionNo())) {
            queryWrapper.eq(DeliverExtDeliverMapping::getConditionNo, deliverExtDeliverMapping.getConditionNo());
        }
        List<DeliverExtDeliverMapping> deliverExtDeliverMappingList = deliverExtDeliverMappingMapper.selectList(queryWrapper);

        if (ObjectUtils.isEmpty(deliverExtDeliverMappingList)) {
            result.setStatus(SUCCESS_STATUS);
            result.addAllExtDeliverMappingList(new ArrayList<>());
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        result.setStatus(SUCCESS_STATUS);
        result.addAllExtDeliverMappingList(deliverGrpcConvertMapper.toGrpcDeliverExtDeliverMappingList(deliverExtDeliverMappingList));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listDeliverExtparams(ListDeliverExtparamsRequest request, StreamObserver<DeliverExtparamsSearchResponse> responseObserver) {
        DeliverExtparamsSearchResponse.Builder result = DeliverExtparamsSearchResponse.newBuilder();
        DeliverExtparams grpcParams = request.getDeliverExtparams();
        DeliverDeliverExtParams deliverDeliverExtParams = deliverGrpcConvertMapper.toDeliverDeliverExtParams(grpcParams);
        LambdaQueryWrapper<DeliverDeliverExtParams> wrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotEmpty(deliverDeliverExtParams)) {
            //后续条件谁用到谁加
            if (ObjectUtil.isNotEmpty(deliverDeliverExtParams.getDeliverId())) {
                wrapper.eq(DeliverDeliverExtParams::getDeliverId, deliverDeliverExtParams.getDeliverId());
            }
            if (ObjectUtil.isNotEmpty(deliverDeliverExtParams.getSurveyId())) {
                wrapper.eq(DeliverDeliverExtParams::getSurveyId, deliverDeliverExtParams.getSurveyId());
            }
            if (ObjectUtil.isNotEmpty(deliverDeliverExtParams.getExtparamId())) {
                wrapper.eq(DeliverDeliverExtParams::getExtparamId, deliverDeliverExtParams.getExtparamId());
            }
        }
        wrapper.in(!ObjectUtil.isEmpty(request.getStatusList()), DeliverDeliverExtParams::getStatus, request.getStatusList());
        List<DeliverDeliverExtParams> deliverextparams_list = deliverDeliverExtParamsMapper.selectList(wrapper);

        if (ObjectUtils.isEmpty(deliverextparams_list)) {
            result.setStatus(SUCCESS_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        result.setStatus(SUCCESS_STATUS);
        result.addAllDeliverExtparamsList(deliverGrpcConvertMapper.toGrpcDeliverExtparamsList(deliverextparams_list));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }


    @Override
    public void listCustomLinkDeliver(ListCustomLinkDeliverRequest request, StreamObserver<CustomLinkDeliverSearchResponse> responseObserver) {
        CustomLinkDeliverSearchResponse.Builder result = CustomLinkDeliverSearchResponse.newBuilder();
        //deliver_id survey_id param_only_aging_type 3个参数
        CustomLinkDeliver grpcParams = request.getCustomLinkDeliver();
        LambdaQueryWrapper<DeliverCustomLinkDeliver> wrapper = new QueryWrapper<>(deliverGrpcConvertMapper.toDeliverCustomLinkDeliver(grpcParams)).lambda();
        List<DeliverCustomLinkDeliver> customLinkDeliverList = deliverCustomLinkDeliverMapper.selectList(wrapper);

        if (ObjectUtils.isEmpty(customLinkDeliverList)) {
            result.setStatus(SUCCESS_STATUS);
            result.addAllCustomLinkDeliverList(new ArrayList<>());
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        result.setStatus(SUCCESS_STATUS);
        result.addAllCustomLinkDeliverList(deliverGrpcConvertMapper.toGrpcCustomLinkDeliverList(customLinkDeliverList));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void listDeliverByIds(ListDeliverByIdsRequest request, StreamObserver<DeliverSearchResponse> responseObserver) {
        DeliverSearchResponse.Builder result = DeliverSearchResponse.newBuilder();
        List<DeliverDeliver> deliverDeliverList = deliverDeliverMapper.selectBatchIds(request.getIdsList());

        if (ObjectUtils.isEmpty(deliverDeliverList)) {
            result.setStatus(FAIL_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }
        List<Deliver> deliverList = new ArrayList<>();

        deliverDeliverList.forEach(a -> deliverList.add(deliverGrpcConvertMapper.toGrpcDeliver(a)));

        result.setStatus(SUCCESS_STATUS);
        result.addAllDeliverList(deliverList);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }


    @Override
    public void getDeliver(GetDeliverRequest request, StreamObserver<DeliverResponse> responseObserver) {
        DeliverResponse.Builder result = DeliverResponse.newBuilder();
        DeliverDeliver deliver = deliverDeliverMapper.selectById(request.getId());
        if (ObjectUtils.isEmpty(deliver)) {
            result.setStatus(FAIL_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        result.setStatus(SUCCESS_STATUS);
        result.setDeliver(deliverGrpcConvertMapper.toGrpcDeliver(deliver));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getWechatMPRecord(GetWechatMPRecordRequest request, StreamObserver<WechatMPRecordResponse> responseObserver) {
        WechatMPRecordResponse.Builder result = WechatMPRecordResponse.newBuilder();
        //获取请求中的id
        String id = request.getId();
        //调用查询函数
        DeliverWechatmpRecord deliverWechatmpRecord = deliverWechatmpRecordMapper.selectById(id);
        if (Objects.isNull(deliverWechatmpRecord)) {
            log.error("deliver.WechatMPRecord[id={}] not found", id);
            result.setStatus(FAIL_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }
        result.setStatus(SUCCESS_STATUS);
        result.setWechatMPRecord(deliverGrpcConvertMapper.toGrpcWechatMPRecord(deliverWechatmpRecord));
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getDeliverIdsByDtPid(GetDeliverIdsByDtPidRequest request, StreamObserver<GetDeliverIdsByDtPidResponse> responseObserver) {
        GetDeliverIdsByDtPidResponse.Builder result = GetDeliverIdsByDtPidResponse.newBuilder();
        String deliverDtGte = request.getDeliverDtGte();
        String deliverDtLt = request.getDeliverDtLt();
        String projectId = request.getProjectId();
        LocalDateTime deliverDtG = LocalDateTimeUtil.parse(deliverDtGte, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        LocalDateTime deliverDtL = LocalDateTimeUtil.parse(deliverDtLt, DateTimeFormatter.ofPattern("yyyyMMddHHmmss")).plusDays(1);
        List<String> deliverIdList = deliverDeliverMapper.getDeliverIdsByDtPid(projectId, deliverDtG, deliverDtL);
        Set<String> deliverIdSet = new HashSet<>(deliverIdList);
        result.setStatus(SUCCESS_STATUS);
        result.setStatus(SUCCESS_STATUS);
        result.addAllDeliverIdList(deliverIdSet);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    @Override
    public void getDeliverSurveyV2(GetDeliverSurveyV2Request request, StreamObserver<GetDeliverSurveyResponse> responseObserver) {
        GetDeliverSurveyResponse.Builder result = GetDeliverSurveyResponse.newBuilder();
        List<String> memberIds = new ArrayList<>(request.getMemberIdsList());
        if (CollectionUtils.isEmpty(memberIds)) {
            result.setStatus(SUCCESS_STATUS);
            responseObserver.onNext(result.build());
            responseObserver.onCompleted();
            return;
        }

        List<DeliverSurvey> surveys = new ArrayList<>();
        for (DeliverDeliverSurveyData deliverSurveyData : getDeliverSurveyDataForCompute(memberIds)) {
            DeliverSurvey.Builder surveyBuilder = DeliverSurvey.newBuilder();
            surveyBuilder.setDeliverId(Optional.ofNullable(deliverSurveyData.getDeliverId()).orElse(""));
            surveyBuilder.setMemberId(Optional.ofNullable(deliverSurveyData.getMemberId()).orElse(""));
            surveyBuilder.setDeliverGroupId(Optional.ofNullable(deliverSurveyData.getDeliverGroupId()).orElse(""));
            surveys.add(surveyBuilder.build());
        }
        result.addAllDeliverSurvey(surveys);
        result.setStatus(SUCCESS_STATUS);
        responseObserver.onNext(result.build());
        responseObserver.onCompleted();
    }

    private List<DeliverDeliverSurveyData> getDeliverSurveyDataForCompute(List<String> memberIds) {
        // 通过member_id 查询出所有的deliver_survey_data
        List<DeliverDeliverSurveyData> results = deliverSurveyDataMapper.selectList(new LambdaQueryWrapper<DeliverDeliverSurveyData>()
                .in(DeliverDeliverSurveyData::getMemberId, memberIds));
        if (CollectionUtils.isEmpty(results)) {
            results = new ArrayList<>();
        }
        return results;
    }
}
